2 K近邻法

1 K 近邻算法

K 近邻算法

输入: 训练数据集 T={(x1,y1),,(xN,yN)}, xiXRn, yiY={c1,,cK}; 实例 x.
输出: x 所属的类别 y.

  1. 根据给定的距离度量,在 T 中找出与 x 最接近的 k 个点, 涵盖这 k 个点的 x 邻域记为 Nk(x);
  2. Nk(x) 中根据分类决策规则 (如多数表决) 决定 x 的类别 y, 也即 (1.1)y=argmaxcjxiNk(x)1yi=cj,1iN,1jK.

2 K 近邻模型

从K 近邻算法看出,距离度量k 值的选取分类决策规则是三个需要定义的要素.

距离

给定 XRn,xi,xjX, 用 x(j) 表示 x 的第 i 个分量,则可以定义 Lp 距离度量(2.1)Lp(xi,xj)=(l=1n|xi(l)xj(l)|p)1p,p1.p=2,称为Euclide 距离; p=1 时,称为 Manhattan 距离;特别地,p=(2.2)L(xi,xj)=maxl|xi(l)xj(l)|.

不同距离度量下,最近邻点可能不同.

# 3 K 近邻法的实现: kd 树 kd 树是为了提高原本线性扫描的搜索效率 . 它的思想是用一系列切分平面将超矩形空间切割成若干子空间,使得每一个数据点都在某一条切割线上. ## 3.1 kd 树的构造 >[!todo]+ 构造平衡 kd 树 > **输入**: $k$维空间数据集$T=\{x_1,\cdots,x_N\}$. > **输出**: kd 树 > 1. **开始: 构造根结点** 找一个包含$T$的$k$维超矩形,取$x^{(1)}$分量的坐标轴,取各数据点的$x^{(1)}$分量的中位数作为切分超平面,将落在超平面的点保存到根结点,将其他点分到两个子结点中(称他们的深度为$1$). > 2. **重复**: 对深度为$j$的结点,选取$x^{(l)}(l=j\mod k+1)$分量的数据点中位数为超平面切分,生成 $j+1$深度的结点. > 3. **停止**: 两个子区域中都不再有数据点 (数据点全部在切分超平面上). > 如果中位数是两个数的平均数,且没有点落在超平面上,则将超平面移到两个数中的一个. >[!faq]- 例子 >依据$T=\{(2,3)^T,(5,4)^T,(9,6)^T,(4,7)^T,(8,1)^T,(7,2)^T\}$构造 kd 树. >我们可以给出作图 <div class="transclusion internal-embed is-loaded"><div class="markdown-embed"> ==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠== You can decompress Drawing data with the command palette: 'Decompress current Excalidraw file'. For more info check in plugin settings under 'Saving' # Excalidraw Data ## Text Elements </div></div> 因此,我们可以据此生成 kd 树: <div class="transclusion internal-embed is-loaded"><div class="markdown-embed"> <div class="markdown-embed-title"> # 400 </div> ==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠== You can decompress Drawing data with the command palette: 'Decompress current Excalidraw file'. For more info check in plugin settings under 'Saving' # Excalidraw Data ## Text Elements </div></div> ## 3.2 kd 树的搜索 >[!todo]+ 用 kd 树的最近邻搜索 >**输入**: kd 树、目标$x$; >**输出**: $x$的最近邻. >1. **寻找叶结点**: 依据目标点的分量和切分点坐标进行比较,寻找叶结点 >2. 以此叶结点为**当前最近点**. >3. 递归地回退,在每个结点判定: >a. 若该结点保存的实例点距离更近,则更新为当前最近点. >b.检查该结点的父结点的另一个字结点区域是否有更近的点 (落在$x$与当前最近点的球体中) >若相交,移动到另一个子结点继续搜索, 然后继续递归; 否则向上回退 >4. 回退到根结点时,**结束**. 输出当前最近点. kd 树的计算复杂度是 $O(\log N)$, 适用于 $N>>n$ 的情形,否则会迅速退化为线性搜索. >[!faq]- 例子 >对如下情形,找到输入点$S$的最近邻. > ![figure/Pasted image 20240617133549.png|300](/img/user/figure/Pasted%20image%2020240617133549.png) >1. 找到包含$S$的叶结点$D$, 当前最近点为$D$. 作以$S$为圆心、$SD$为半径的圆; >2. 回退到$D$的父结点$B$, 寻找$B$的另一子结点$F$, 发现与圆不相交; >3. 回退到$B$的父结点$A$, 寻找$A$的另一子结点$C$, 发现$E$落在圆内,更新为当前最近点; >4. 输出$E$.